package org.robcash.flexlib.controls.dataGridClasses
{
    import flash.text.StyleSheet;
    import flash.text.TextFormat;
    
    import mx.containers.Canvas;
    import mx.controls.DataGrid;
    import mx.controls.Text;
    import mx.controls.dataGridClasses.DataGridColumn;
    import mx.controls.dataGridClasses.DataGridListData;
    import mx.controls.listClasses.BaseListData;
    import mx.controls.listClasses.IDropInListItemRenderer;
    import mx.controls.listClasses.IListItemRenderer;
    import mx.core.UIComponent;
    import mx.events.FlexEvent;

	/**
	 * Render HTML for use within a data grid.
	 * This came from http://www.actionscript.org/forums/showthread.php3?t=107897
	 */
	public class HTMLRenderer extends UIComponent implements IDropInListItemRenderer, IListItemRenderer
	{
        [Bindable( "dataChange" )]
        
        protected var _data:Object;
        protected var _listData:BaseListData;
        protected var _container:Canvas;
        protected var _textControl:Text;
        protected var _textFormat:TextFormat;
        protected var _styleSheet:StyleSheet;
        
        public function HTMLRenderer()
        {
            super();
        }      
        
        /**
         * Returns the data value.
         * IListItemRenderer method
         * 
         * @returns Object
         * @see IListItemRenderer
         */
        public function get data():Object
        {
            return _data;
        }
        
        /**
         * Commits the received object to the data property, invalidates properties,
         * and dispatches a dataChange events.
         * IListItemRenderer method
         * 
         * @param value Object
         * @see IListItemRenderer
         */
        public function set data( value:Object ):void
        {
            _data = value;
            invalidateProperties();
            dispatchEvent( new FlexEvent( FlexEvent.DATA_CHANGE ) );
        }
        
        /**
         * Returns the listData value.
         * IDropInListItemRenderer method
         * 
         * @returns BaseListData
         * @see     IDropInListItemRenderer
         */
        public function get listData():BaseListData
        {
            return _listData;
        }
        
        /**
         * Commits the listData and invalidates properties.
         * IDropInListItemRenderer method
         * 
         * @param value BaseListData
         * @see IDropInListItemRenderer
         */
        public function set listData( value:BaseListData ):void
        {
            _listData = value;
            trace("Column index is: " + value.columnIndex);
            if ( value.owner is DataGrid )
            {
            	_container.maxWidth = DataGridColumn(DataGrid(value.owner).columns[value.columnIndex]).width;
            	trace("Set max width of container to: " + _container.maxWidth); 
            }
            invalidateProperties();
        }
        
        /**
         * Creates all child elements and ensure they are in the display list.
         */
        override protected function createChildren():void 
        {
            super.createChildren();
            
            if ( _container == null )
            {
                _container = new Canvas();
                _container.horizontalScrollPolicy = "off";
                _container.verticalScrollPolicy = "off";
                _container.percentWidth = 100;
                _container.percentHeight = 100;
                addChild( _container );
                
                _textControl = new Text();
                _textControl.percentWidth = 100;
                _textControl.percentHeight = 100;
				_textControl.selectable = false;
                _container.addChild( _textControl );
            }
            else if ( !this.numChildren )
            {
                addChild( _container );
            }
        }        
        
        /**
         * Commits all properties and sets the visible HTML text. This is where
         * the magic happens. Called by the framework during init and invalidateProperties.
         */
        override protected function commitProperties():void 
        {
            super.commitProperties();
            
            // Determine the value of htmlText.
            var value:String = "";
            var dataField:String = "htmlText"; // default.
            try
            {
                // Set the htmlText to the label, which will appropriately handle labelFunctions
                value = DataGridListData( listData ).label;
				var myPattern:RegExp = /\\\'/g;
				var myPattern2:RegExp = /\\\"/g;
				value = value.replace(myPattern, "'");
				value = value.replace(myPattern2, "\"");
            }
            catch ( err:Error ) 
            { 
                // Ignore error, try to handle another way.
                if ( _data != null && _data[ dataField ] != null )
                {
                    if ( _data[ dataField ] is String ) { value = _data[ dataField ]; }
                    else { value = _data[ dataField ].toString(); }
                }
            }
            // Set the htmlText!
            _textControl.htmlText = value;
            invalidateSize();
        }
        
        /**
         * Measure informs the parent object what the preferred size should be.
         * This will be ignored if an explicit width and height are set.
         * Called by the framework during init and invalidateSize.
         */
        override protected function measure():void
        {
            super.measure();
            if ( _container != null )
            {
                measuredWidth = Math.min(_container.width, _container.maxWidth);
                measuredHeight = Math.max(_container.height, _textControl.measureHTMLText(_textControl.htmlText).height);
            }
        }

        /**
         * Position and size child elements and call all drawing API methods.
         * Called by the framework during init and invalidateDisplayList.
         */
        override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
        {
            super.updateDisplayList( unscaledWidth, unscaledHeight );         
            _container.width = unscaledWidth;
            _container.height = unscaledHeight;   
        }      
    }
}